import { ref, computed, reactive } from 'vue'
import { Character } from '../character/Character'

/**
 * 场景配置
 */
export interface SceneConfig {
  width: number
  height: number
  backgroundColor: string
  fps: number
  duration: number // 场景时长（帧数）
}

/**
 * 摄像机配置
 */
export interface Camera {
  x: number
  y: number
  zoom: number
  rotation: number
  followTarget?: string // 跟随的角色ID
}

/**
 * 场景背景
 */
export interface Background {
  type: 'color' | 'image' | 'gradient'
  value: string | { colors: string[]; direction: number }
  asset?: {
    id: string
    url: string
    width: number
    height: number
  }
}

/**
 * 场景类
 */
export class Scene {
  public readonly id: string
  public name = ref('')
  
  // 场景配置
  public config = reactive<SceneConfig>({
    width: 1280,
    height: 720,
    backgroundColor: '#ffffff',
    fps: 30,
    duration: 300
  })
  
  // 摄像机
  public camera = reactive<Camera>({
    x: 0,
    y: 0,
    zoom: 1,
    rotation: 0
  })
  
  // 背景
  public background = reactive<Background>({
    type: 'color',
    value: '#ffffff'
  })
  
  // 角色列表
  public characters = ref<Character[]>([])
  
  // 当前帧
  public currentFrame = ref(0)
  
  // 是否被选中
  public selected = ref(false)
  
  constructor(id: string, name: string = '') {
    this.id = id
    this.name.value = name || `Scene_${id.slice(0, 8)}`
  }
  
  /**
   * 添加角色到场景
   */
  public addCharacter(character: Character): void {
    if (!this.characters.value.find(c => c.id === character.id)) {
      this.characters.value.push(character)
      this.sortCharactersByZIndex()
    }
  }
  
  /**
   * 从场景移除角色
   */
  public removeCharacter(characterId: string): boolean {
    const index = this.characters.value.findIndex(c => c.id === characterId)
    if (index >= 0) {
      this.characters.value.splice(index, 1)
      return true
    }
    return false
  }
  
  /**
   * 根据ID获取角色
   */
  public getCharacter(characterId: string): Character | undefined {
    return this.characters.value.find(c => c.id === characterId)
  }
  
  /**
   * 按Z轴排序角色
   */
  public sortCharactersByZIndex(): void {
    this.characters.value.sort((a, b) => a.zIndex.value - b.zIndex.value)
  }
  
  /**
   * 设置角色Z轴顺序
   */
  public setCharacterZIndex(characterId: string, zIndex: number): void {
    const character = this.getCharacter(characterId)
    if (character) {
      character.zIndex.value = zIndex
      this.sortCharactersByZIndex()
    }
  }
  
  /**
   * 将角色移到最前面
   */
  public bringCharacterToFront(characterId: string): void {
    const maxZ = Math.max(...this.characters.value.map(c => c.zIndex.value), 0)
    this.setCharacterZIndex(characterId, maxZ + 1)
  }
  
  /**
   * 将角色移到最后面
   */
  public sendCharacterToBack(characterId: string): void {
    const minZ = Math.min(...this.characters.value.map(c => c.zIndex.value), 0)
    this.setCharacterZIndex(characterId, minZ - 1)
  }
  
  /**
   * 更新场景到指定帧
   */
  public updateToFrame(frame: number): void {
    this.currentFrame.value = Math.max(0, Math.min(frame, this.config.duration - 1))
    
    // 更新所有角色到当前帧
    this.characters.value.forEach(character => {
      character.updateAtFrame(this.currentFrame.value)
    })
    
    // 更新摄像机（如果有跟随目标）
    this.updateCamera()
  }
  
  /**
   * 更新摄像机
   */
  private updateCamera(): void {
    if (this.camera.followTarget) {
      const target = this.getCharacter(this.camera.followTarget)
      if (target) {
        this.camera.x = target.transform.x
        this.camera.y = target.transform.y
      }
    }
  }
  
  /**
   * 设置背景
   */
  public setBackground(background: Partial<Background>): void {
    Object.assign(this.background, background)
  }
  
  /**
   * 设置摄像机跟随目标
   */
  public setCameraFollowTarget(characterId: string | undefined): void {
    this.camera.followTarget = characterId
  }
  
  /**
   * 获取场景在指定帧的所有可见角色
   */
  public getVisibleCharactersAtFrame(frame: number): Character[] {
    return this.characters.value.filter(character => {
      const properties = character.getInterpolatedProperties(frame)
      return properties.visible && properties.opacity > 0
    })
  }
  
  /**
   * 检查点是否在场景边界内
   */
  public isPointInBounds(x: number, y: number): boolean {
    return x >= 0 && x <= this.config.width && y >= 0 && y <= this.config.height
  }
  
  /**
   * 将屏幕坐标转换为场景坐标
   */
  public screenToScene(screenX: number, screenY: number): { x: number; y: number } {
    const { x: camX, y: camY, zoom } = this.camera
    
    return {
      x: (screenX / zoom) + camX,
      y: (screenY / zoom) + camY
    }
  }
  
  /**
   * 将场景坐标转换为屏幕坐标
   */
  public sceneToScreen(sceneX: number, sceneY: number): { x: number; y: number } {
    const { x: camX, y: camY, zoom } = this.camera
    
    return {
      x: (sceneX - camX) * zoom,
      y: (sceneY - camY) * zoom
    }
  }
  
  /**
   * 获取场景边界框
   */
  public getBounds(): { x: number; y: number; width: number; height: number } {
    return {
      x: 0,
      y: 0,
      width: this.config.width,
      height: this.config.height
    }
  }
  
  /**
   * 克隆场景
   */
  public clone(newId: string): Scene {
    const cloned = new Scene(newId, `${this.name.value}_copy`)
    
    // 复制配置
    Object.assign(cloned.config, this.config)
    
    // 复制摄像机
    Object.assign(cloned.camera, this.camera)
    
    // 复制背景
    Object.assign(cloned.background, this.background)
    
    // 复制角色
    cloned.characters.value = this.characters.value.map(character => 
      character.clone(`${character.id}_copy`)
    )
    
    return cloned
  }
  
  /**
   * 导出场景数据
   */
  public export(): any {
    return {
      id: this.id,
      name: this.name.value,
      config: { ...this.config },
      camera: { ...this.camera },
      background: { ...this.background },
      characters: this.characters.value.map(character => character.export()),
      currentFrame: this.currentFrame.value
    }
  }
  
  /**
   * 从数据导入场景
   */
  public import(data: any): void {
    this.name.value = data.name || this.name.value
    
    if (data.config) {
      Object.assign(this.config, data.config)
    }
    
    if (data.camera) {
      Object.assign(this.camera, data.camera)
    }
    
    if (data.background) {
      Object.assign(this.background, data.background)
    }
    
    if (data.characters) {
      this.characters.value = data.characters.map((charData: any) => {
        const character = new Character(charData.id, charData.name)
        character.import(charData)
        return character
      })
    }
    
    this.currentFrame.value = data.currentFrame || 0
  }
  
  /**
   * 计算属性：场景时长（秒）
   */
  public get durationInSeconds() {
    return computed(() => this.config.duration / this.config.fps)
  }
  
  /**
   * 计算属性：当前时间（秒）
   */
  public get currentTimeInSeconds() {
    return computed(() => this.currentFrame.value / this.config.fps)
  }
  
  /**
   * 计算属性：场景宽高比
   */
  public get aspectRatio() {
    return computed(() => this.config.width / this.config.height)
  }
  
  /**
   * 计算属性：可见角色数量
   */
  public get visibleCharacterCount() {
    return computed(() => 
      this.getVisibleCharactersAtFrame(this.currentFrame.value).length
    )
  }
}
